/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.service.core.impl;

import com.blandware.atleap.common.util.PartialCollection;
import com.blandware.atleap.common.util.QueryInfo;
import com.blandware.atleap.model.core.Layout;
import com.blandware.atleap.model.core.TileContainer;
import com.blandware.atleap.persistence.core.LayoutDAO;
import com.blandware.atleap.persistence.core.TileContainerDAO;
import com.blandware.atleap.persistence.exception.DeleteException;
import com.blandware.atleap.persistence.exception.UpdateException;
import com.blandware.atleap.service.core.LayoutManager;
import com.blandware.atleap.service.exception.BeanAlreadyExistsException;
import com.blandware.atleap.service.exception.BeanNotFoundException;
import com.blandware.atleap.service.exception.OwnerNotFoundException;

import java.util.List;

/**
 * <p>Implementation of LayoutManager</p>
 * <p><a href="LayoutManagerImpl.java.html"><i>View Source</i></a>
 * </p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.14 $ $Date: 2007/04/08 15:07:14 $
 */
public class LayoutManagerImpl extends BaseManagerImpl implements LayoutManager {

	// ~ Instance variables ================================================================


	/**
	 * DAO to use to get access to persistence layer
	 */
	protected LayoutDAO layoutDAO;
    /**
     * DAO to work with tile containers
     */
    protected TileContainerDAO tileContainerDAO;

    /**
     * Sets layout DAO.
     *
     * @param layoutDAO Layout DAO to use
     */
    public void setLayoutDAO(LayoutDAO layoutDAO) {
        this.layoutDAO = layoutDAO;
    }

    /**
     * Sets tile container DAO.
     *
     * @param tileContainerDAO DAO to set
     */
    public void setTileContainerDAO(TileContainerDAO tileContainerDAO) {
        this.tileContainerDAO = tileContainerDAO;
    }

    //  L A Y O U T S

    //~ CRUD Methods ================================================================

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#createLayout(com.blandware.atleap.model.core.Layout)
	 */
	public Long createLayout(Layout layout) throws BeanAlreadyExistsException {
		if ( log.isDebugEnabled() ) {
			log.debug("Creating new layout...");
		}

		if ( layoutDAO.hasDuplicates(layout) ) {
			throw new BeanAlreadyExistsException("Layout with the same name or definition already exists");
		}

		Long layoutId = layoutDAO.createLayout(layout);
		if ( log.isDebugEnabled() ) {
			log.debug("Layout has been created successfully. Its ID is " + layoutId);
		}
		return layoutId;
	}

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#retrieveLayout(java.lang.Long)
	 */
	public Layout retrieveLayout(Long layoutId) {
		Layout layout;
		layout = layoutDAO.retrieveLayout(layoutId);
		return layout;
	}

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#updateLayout(com.blandware.atleap.model.core.Layout)
	 */
	public void updateLayout(Layout layout) throws BeanAlreadyExistsException, BeanNotFoundException, UpdateException {
        // remove layout from cache in order to prevent Hibernate from assigning new version number
		layoutDAO.removeFromCache(layout);
		if ( log.isDebugEnabled() ) {
			log.debug("Updating layout with ID=" + layout.getId());
		}

		if ( layoutDAO.hasDuplicates(layout) ) {
			throw new BeanAlreadyExistsException("Layout with the same name or definition already exists");
		}

		// update layout
		layoutDAO.updateLayout(layout);


	}

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#deleteLayout(java.lang.Long)
	 */
	public void deleteLayout(Long layoutId) throws DeleteException, BeanNotFoundException {
		Layout layout = layoutDAO.retrieveLayout(layoutId);
		if ( layout == null ) {
			String errorMessage = "No layout with ID=" + layoutId + " could be found";
			throw new BeanNotFoundException(errorMessage);
		}
		layoutDAO.deleteLayout(layout);
	}

	// ~ Additional methods ================================================================

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#listLayouts(com.blandware.atleap.common.util.QueryInfo)
	 */
	public PartialCollection listLayouts(QueryInfo queryInfo) {
		return layoutDAO.listLayouts(queryInfo);
	}

	// ~ Finders ================================================================

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#findLayoutByContentPageUri(java.lang.String)
	 */
	public Layout findLayoutByContentPageUri(String contentPageUri) {

		// Find content page by specified uri

		if ( log.isDebugEnabled() ) {
			log.debug("Looking for layout by content page uri: " + contentPageUri);
		}
		Layout layout;
		layout = layoutDAO.findLayoutByContentPageUri(contentPageUri);
		return layout;
	}

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#findLayoutByDefinition(java.lang.String)
	 */
	public Layout findLayoutByDefinition(String definitionName) {
		Layout layout;
		layout = layoutDAO.findLayoutByDefinition(definitionName);
		return layout;
	}

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#findLayoutByName(java.lang.String)
	 */
	public Layout findLayoutByName(String name) {
		Layout layout;
		layout = layoutDAO.findLayoutByName(name);
		return layout;
	}

    //  T I L E   C O N T A I N E R S

    //~ CRUD Methods ================================================================

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#createTileContainer(com.blandware.atleap.model.core.TileContainer, Long)
	 */
	public Long createTileContainer(TileContainer container, Long layoutId)
            throws BeanAlreadyExistsException, BeanNotFoundException {
		if ( log.isDebugEnabled() ) {
			log.debug("Creating new tile container...");
		}

        Layout layout = layoutDAO.retrieveLayout(layoutId);
		if ( layout == null ) {
			// layout does not exist
			String errorMessage = "Layout with ID=" + layoutId
                    + " does not exist";
			if ( log.isErrorEnabled() ) {
				log.error(errorMessage);
			}
			throw new OwnerNotFoundException(errorMessage);
		}

        if ( tileContainerDAO.hasDuplicates(container) ) {
			throw new BeanAlreadyExistsException("Tile container with the same definition and list names already exists on same layout");
		}

		Long tileContainerId = tileContainerDAO.createTileContainer(container, layout);
		if ( log.isDebugEnabled() ) {
			log.debug("Tile container has been created successfully. Its ID is "
                    + tileContainerId);
		}
		return tileContainerId;
    }

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#retrieveTileContainer(Long)
	 */
	public TileContainer retrieveTileContainer(Long tileContainerId) {
		TileContainer tileContainer;
		tileContainer = tileContainerDAO.retrieveTileContainer(tileContainerId);
		return tileContainer;
	}

    /**
     * @see com.blandware.atleap.service.core.LayoutManager#updateTileContainer(com.blandware.atleap.model.core.TileContainer)
     */
    public void updateTileContainer(TileContainer tileContainer)
            throws BeanAlreadyExistsException, BeanNotFoundException {
        // remove tile container from cache in order to prevent Hibernate from
        // assigning new version number
        tileContainerDAO.removeFromCache(tileContainer);
        if ( log.isDebugEnabled() ) {
            log.debug("Updating tile container with ID=" + tileContainer.getId());
        }

        if ( tileContainerDAO.hasDuplicates(tileContainer) ) {
            throw new BeanAlreadyExistsException("Tile container with the same definition and list names already exists on same layout");
        }

        // update tile container
        tileContainerDAO.updateTileContainer(tileContainer);
    }

    /**
	 * @see com.blandware.atleap.service.core.LayoutManager#deleteTileContainer(Long)
	 */
	public void deleteTileContainer(Long containerId) throws BeanNotFoundException {
		TileContainer tileContainer
                = tileContainerDAO.retrieveTileContainer(containerId);
		if ( tileContainer == null ) {
			String errorMessage = "No tile container with ID="
                    + containerId + " could be found";
			throw new BeanNotFoundException(errorMessage);
		}
		tileContainerDAO.deleteTileContainer(tileContainer);
	}

	// ~ Additional methods ================================================================

	/**
	 * @see com.blandware.atleap.service.core.LayoutManager#listTileContainers(com.blandware.atleap.common.util.QueryInfo)
	 */
	public PartialCollection listTileContainers(QueryInfo queryInfo) {
		return tileContainerDAO.listTileContainers(queryInfo);
	}

    // ~ Finders ================================================================

    /**
     * @see com.blandware.atleap.service.core.LayoutManager#findTileContainersByLayoutId(Long)
     */
    public List findTileContainersByLayoutId(Long layoutId) {
        return tileContainerDAO.findTileContainersByLayoutId(layoutId);
    }

    /**
     * @see com.blandware.atleap.service.core.LayoutManager#findTileContainerByLayoutIdAndIdentifier(Long, String) 
     */
    public TileContainer findTileContainerByLayoutIdAndIdentifier(Long layoutId,
            String identifier) {
        return tileContainerDAO.findTileContainerByLayoutIdAndIdentifier(layoutId,
                identifier);
    }
}
